import 'dart:developer';

import 'package:FlutterDemo/common/commons.dart';
import 'package:bloc/bloc.dart';
import 'package:flutter/material.dart';

/// https://www.jianshu.com/p/36318f19b570
class SampleBloc2Widget extends StatefulWidget {
  const SampleBloc2Widget({Key? key}) : super(key: key);

  @override
  _SampleBloc2WidgetState createState() => _SampleBloc2WidgetState();
}

class _SampleBloc2WidgetState extends State<SampleBloc2Widget> {
  CounterBloc bloc = CounterBloc(0);
  var num = 0;

  @override
  void initState() {
    super.initState();

    // 移至app入口
    // 单例对象
    // BlocSupervisor.delegate = SimpleBlocDelegate();
    // // 创建Bloc
    // var bloc = CounterBloc();
    // // 添加事件
    // for (var i = 0; i < 3; i++) {
    //   bloc.add(CounterEvent.increment);
    // }
    // // 添加null
    // bloc.add(null);
    //
    // for (var i = 0; i < 3; i++) {
    //   bloc.add(CounterEvent.decrement);
    // }
  }

  @override
  Widget build(BuildContext context) {
    return SingleChildScrollView(
      child: Column(
        children: [
          Text("简单使用Bloc"),
          Container(
            margin: EdgeInsets.only(bottom: 20),
            child: Column(
              children: [
                Text("当前计数: $num , 下一个数值为: ${bloc.state}"),
                buildCommonRaisedButton("+", 20.0, () {
                  bloc.add(CounterEvent.increment);
                  setState(() {
                    num = bloc.state;
                  });
                }),
                buildCommonRaisedButton("-", 20.0, () {
                  bloc.add(CounterEvent.decrement);
                  setState(() {
                    num = bloc.state;
                  });
                }),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

/// Events
/// Events 是 Bloc 的输入，通常是为了响应用户交互或生命周期事件而添加它们。当用户点击按钮时，发送一个事件
/// 定义事件
enum CounterEvent { increment, decrement }

/// States
// States 是 Bloc 的输出, 代表应用程序状态的一部分。可以通知UI组件状态，并根据当前状态重绘其自身的某些部分。

/// Transitions
// Transitions 是从一种状态到另一种状态的，过渡由当前状态，事件和下一个状态组成
//{"currentState":0,"event:":"CounterEvent.increment","nextState":1}

/// Streams
// Blocs
// Bloc(业务逻辑组件) 是将Stream输入的Events 转换Stream为输出的组件States。
//
// 每个Bloc必须继承自Bloc基类。
// 每个Bloc必须定义一个初始状态, 该状态是接收任何事件之前的状态。
// 每个Bloc必须实现mapEventToState函数, 该函数将传入event作为参数，并且必须返回Stream的新states。我们可以使用state属性随时访问当前的块状态。
//
/// 定义Bloc,必须继承Bloc
class CounterBloc extends Bloc<CounterEvent, int> {
  CounterBloc(int initialState) : super(initialState);

  // 必须 实现初始化状态
  @override
  int get initialState => 0;

  // 必须实现mapEventToState
  @override
  Stream<int> mapEventToState(CounterEvent event) async* {
    log("CounterBloc mapEventToState");
    // 根据不同的事件处理
    switch (event) {
      case CounterEvent.increment:
        log("CounterBloc mapEventToState 处理添加事件");
        // 添加事件
        yield state + 1;
        break;
      case CounterEvent.decrement:
        log("CounterBloc mapEventToState 处理删除事件");
        // 删除事件
        yield state - 1;
        break;
      default:
        throw Exception("unhandled event: $event");
    }
  }

  // 记录转换过程
  @override
  void onTransition(Transition<CounterEvent, int> transition) {
    super.onTransition(transition);
    log("CounterBloc onTransition $transition");
  }

  // 异常
  @override
  void onError(Object error, StackTrace stacktrace) {
    super.onError(error, stacktrace);

    log("CounterBloc onError: $error");
  }
}
